// Fill out your copyright notice in the Description page of Project Settings.

#include "WebcamUpdater.h"
#include <Rendering/Texture2DResource.h>

AWebcamUpdater::AWebcamUpdater()
{
	PrimaryActorTick.bCanEverTick = true;
	_cameraID = 0;
	_isOpen = false;
	_videoSize = FVector2D(0, 0);
}

void AWebcamUpdater::BeginPlay()
{
	_capturer = cv::VideoCapture(_cameraID);
	if (_capturer.isOpened())
	{
		if (_capturer.read(_frame))
		{
			_videoTexture = UTexture2D::CreateTransient(_frame.cols, _frame.rows);
			_videoTexture->UpdateResource();
			_videoSize = FVector2D(_frame.cols, _frame.rows);
			_isOpen = true;

			_data.Init(FColor(0, 0, 0, 255), _frame.cols * _frame.rows);
			_region = new FUpdateTextureRegion2D(0, 0, 0, 0, _frame.cols, _frame.rows);
			UpdateTextureData();
		}
	}
	Super::BeginPlay();
}

void AWebcamUpdater::UpdateTextureData()
{
	for (int y = 0; y < _frame.rows; ++y)
	{
		for (int x = 0; x < _frame.cols; ++x)
		{
			int index = x + (y * _frame.cols);
			_data[index].B = _frame.data[index * 3 + 0];
			_data[index].G = _frame.data[index * 3 + 1];
			_data[index].R = _frame.data[index * 3 + 2];
		}
	}

	struct FUpdateTextureRegionsData
	{
		FTexture2DResource* Texture2DResource;
		FUpdateTextureRegion2D* Regions;
		uint32 SrcPitch;
		uint8* SrcData;
	};

	FUpdateTextureRegionsData* regionData = new FUpdateTextureRegionsData;
	regionData->Texture2DResource = (FTexture2DResource*)_videoTexture->Resource;
	regionData->Regions = _region;
	regionData->SrcPitch = (uint32)(4 * _frame.cols);
	regionData->SrcData = (uint8*)_data.GetData();

	ENQUEUE_RENDER_COMMAND(UpdateTextureRegionsData)(
		[regionData](FRHICommandListImmediate& RHICmdList)
	{
		RHIUpdateTexture2D(
			regionData->Texture2DResource->GetTexture2DRHI(),
			0, *(regionData->Regions), regionData->SrcPitch, regionData->SrcData);
		delete regionData;
	});
}

void AWebcamUpdater::Tick(float DeltaTime)
{
	if (_capturer.read(_frame)) UpdateTextureData();
	Super::Tick(DeltaTime);
}
